package com.spa.interfaces.member;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.spa.application.command.Login;
import com.spa.application.dto.login.LoginDTO;
import com.spa.application.query.member.*;
import com.spa.application.service.common.LoginApplicationService;
import com.spa.infrastructure.common.CommonCode;
import com.spa.infrastructure.common.ResponseMessage;
import com.spa.infrastructure.enums.dict.base.RequestSourceEnum;
import com.spa.infrastructure.enums.dict.base.SourceTypeEnum;
import com.spa.infrastructure.exception.SpaException;
import com.spa.infrastructure.service.douyin.DouYinMiNiService;
import com.spa.infrastructure.service.douyin.result.GetPhoneResult;
import com.spa.infrastructure.service.sms.GenerateSmsCodeKey;
import com.spa.infrastructure.service.sms.SmsProvider;
import com.spa.infrastructure.util.SessionUtil;
import com.spa.interfaces.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("member")
@Slf4j
public class MemberLoginController extends BaseController {

    @Resource
    private LoginApplicationService loginService;

    @Resource
    private GenerateSmsCodeKey smsCodeKey;

    private DouYinMiNiService douYinMiNiService;

    @Resource
    private SmsProvider smsProvider;

    @PostMapping("/smsLogin")
    @SaIgnore
    public ResponseMessage<LoginDTO> smsLogin(@Validated @RequestBody LoginQuery query) {
        SourceTypeEnum stEnum = SourceTypeEnum.byCode(query.getSource());
        Login login = new Login();
        BeanUtil.copyProperties(query, login);
        LoginDTO loginDTO = loginService.memberAuthSmsRegisterLogin(login, stEnum);
        return responseHelper.success(loginDTO);
    }

    @PostMapping("/authLogin")
    @SaIgnore
    public ResponseMessage<LoginDTO> authLogin(@Validated @RequestBody MemberAuthLoginQuery query) {
        SourceTypeEnum sourceTypeEnum = SourceTypeEnum.byCode(query.getSource());
        Login login = new Login();
        login.setCode(query.getCode());
        login.setAuthId(query.getOpenid());
        if (SourceTypeEnum.DouYinMiNi.equals(sourceTypeEnum)) {
            //解密手机号
            try {
                GetPhoneResult getPhoneResult = douYinMiNiService.decrypt(query.getEncryptedData(), query.getSessionKey(), query.getIv());
                login.setPhone(getPhoneResult.getPurePhoneNumber());
            } catch (Exception e) {
                throw new SpaException("获取手机号失败，" + e.getMessage());
            }
        }
        LoginDTO loginDTO = loginService.memberAuthLogin(login, sourceTypeEnum);
        return responseHelper.success(loginDTO);
    }

    @PostMapping("/officialAccounts")
    @SaIgnore
    public ResponseMessage<LoginDTO> officialAccounts(@Validated @RequestBody MemberWeChatLoginQuery query) {
        Login login = new Login();
        BeanUtil.copyProperties(query, login);
        login.setAuthId(query.getOpenId());
        LoginDTO loginDTO = loginService.memberAuthSmsRegisterLogin(login, SourceTypeEnum.WeChat);
        return responseHelper.success(loginDTO);
    }

    @PostMapping("/outLogin")
    public ResponseMessage outLogin() {
        StpUtil.logout();
        return responseHelper.success();
    }

    @PostMapping("/loginVerify")
    @SaIgnore
    public ResponseMessage loginVerify() {
        if (StpUtil.isLogin()) {
            return responseHelper.success();
        }
        return responseHelper.fail(CommonCode.UN_LOGIN);
    }

    @PostMapping("/wxConcerned")
    public ResponseMessage wxopen() {
        return responseHelper.success(loginService.getWxConcerned(SessionUtil.getUser().getUserId(), RequestSourceEnum.Member));
    }

    @PostMapping("/sendSms")
    @SaIgnore
    public ResponseMessage sendSms(@Validated @RequestBody SmsQuery query) {
        String key = smsCodeKey.generateSmsCodeKey(query.getPhone(), RequestSourceEnum.Member.getCode());
        smsProvider.sendVerificationCode(query.getPhone(), key);
        return responseHelper.success();
    }

}
